package cn.mengfly.testnrz.crazyIm.nettyserver;

import cn.mengfly.testnrz.crazyIm.ServerConstants;
import cn.mengfly.testnrz.curator.ZkClient;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.atomic.AtomicValue;
import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
import org.apache.curator.retry.RetryNTimes;

/**
 * 分布式计数器
 *
 * @author Mengfly
 */
public class OnlineCounter {

    private static final int QTY = 5;
    private static final String PATH = ServerConstants.COUNTER_PATH;

    private CuratorFramework client = null;

    private static OnlineCounter instance = null;

    DistributedAtomicLong onlineCounter = null;

    public static OnlineCounter getInst() {
        if (null == instance) {
            synchronized (OnlineCounter.class) {
                if (null == instance) {
                    instance = new OnlineCounter();
                    instance.client = ZkClient.inst().getClient();
                    instance.init();
                }
            }
        }
        return instance;
    }

    private OnlineCounter() {

    }

    /**
     * 增加计数
     */
    public boolean increment() {
        boolean result = false;
        AtomicValue<Long> val = null;
        try {
            val = onlineCounter.increment();
            result = val.succeeded();
            System.out.println("old cnt:" + val.preValue() + " new cnt:" + val.postValue() + " result:" + val.succeeded());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 减少计数
     */
    public boolean decrement() {
        boolean result = false;
        AtomicValue<Long> val = null;
        try {
            val = onlineCounter.decrement();
            result = val.succeeded();
            System.out.println("old cnt:" + val.preValue() + " new cnt:" + val.postValue() + " result:" + val.succeeded());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private void init() {
        // 分布式计数器，失败重试10， 每次间隔30毫秒
        onlineCounter = new DistributedAtomicLong(
                client, PATH, new RetryNTimes(10, 30));
    }
}
